package in.waffl.fairycake;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.io.IOException;
import java.util.ArrayList;

public class Cake extends Character {
	private boolean falling = false;
	private boolean crumbling = false;
	private final Character target;
	private final Monster pastLife;
	private int damage = 0;
	private static final ArrayList<Cake> cakes = new ArrayList<Cake>();
	private static final int resilience = 5;
	public Cake(int x, int y, final Canvas canvas, Monster pastLife, Character target) {
		super(x, y, 31, 30);
		this.pastLife = pastLife;
		this.target = target;
		cakes.add(this);
		try {
			setSprite(new Sprite(Ptolemy.class.getResourceAsStream("/in/waffl/fairycake/data/Cake.png"), getWidth(), getHeight(), Color.magenta));
		} catch (IOException e) {
			e.printStackTrace();
		}
		this.drawable = new Drawable() {
			@Override
			public void draw(Graphics2D g) {
				getSprite().draw(g, canvas, getX(), getY(), getImageIndex());
			}
		};
		canvas.addDrawable(drawable);
	}

	protected void characterPoll(PollingThread p) {
		if (getVspeed() > 2) {
			falling = true;
		}
		if (getDamage() > resilience) crumbling = true;
		if (crumbling) {
			crumble();
		} else {
			//push around
			Monster monstCollision = Monster.collisionRectangle(new Rectangle(getX(), getY(), getWidth(), getHeight()));
			boolean targetCollision = collisionRect(new Rectangle(target.getX(), target.getY(), target.getWidth(), target.getHeight()));
			Character charCollision = target;
			if (!targetCollision) charCollision = monstCollision;
			if (charCollision == null) charCollision = Cake.collisionCake(this);
			if (charCollision != null && (charCollision.hasMovedH() || charCollision.getClass() == Cake.class)) {
				charCollision.setPushing();
				int targetX = charCollision.getX() - 30;
				if (charCollision.getDirection() == Direction.RIGHT) {
					targetX = charCollision.getX() + charCollision.getWidth();
				}
				int d = charCollision.getDirection() == Direction.LEFT ? -1 : 1;
				for (int i = 0; i < 4; i++) {
					if (getX() != targetX) setX(getX() + d);
				}
			}
			if (targetCollision && monstCollision != null && !monstCollision.isDirectionSet()) {
				if (monstCollision.getX() > getX() + 10) {
					if (monstCollision.getCollisionRight() == null) {
						monstCollision.setDirection(Direction.RIGHT);
						monstCollision.setX(getX() + getWidth() + 2);
					} else {
						target.setX(target.getX() - 12);
						this.setX(getX() - 12);
						monstCollision.triggerJump(Direction.LEFT);
					}
				} else {
					if (monstCollision.getCollisionLeft() == null) {
						monstCollision.setDirection(Direction.LEFT);
						monstCollision.setX(getX() - getWidth() - 2);
					} else {
						target.setX(target.getX() + 12);
						this.setX(getX() + 12);
						monstCollision.triggerJump(Direction.RIGHT);
					}
				}
			}
			//crush things
//			Character charColBottom = Monster.collisionRectangle(new Rectangle(getX(), getY() + getHeight(), getWidth(), getHeight()));
//			if (charColBottom != null && getVspeed() > 2) charColBottom.die();
		}
	}

	protected void onLanding() {
		if (falling && !crumbling) this.crumble();
	}
	
	protected void onDestroy() {
		cakes.remove(this);
	}
	
	public static int getCakeCount() {
		return cakes.size();
	}
	
	private void crumble() {
		final int animationSpeed = 8;
		crumbling = true;
		if (getImageIndex() == 5) {
			this.destroy();
			pastLife.setX(getX());
			pastLife.setY(getY());
			pastLife.die();
		}
		setImageIndex((walkAnim/animationSpeed)%6);
		walkAnim++;
	}
	
	private boolean collisionRect(Rectangle r) {
		return r.intersects(new Rectangle(getX(), getY(), getWidth(), getHeight()));
	}
	
	public static Cake collisionRectangle(Rectangle r) {
		for (Cake c : cakes) {
			if (r.intersects(new Rectangle(c.getX(), c.getY(), c.getWidth(), c.getHeight()))) return c;
		}
		return null;
	}
	
	public static Cake collisionCake(Cake cake) {
		Rectangle r = new Rectangle(cake.getX(), cake.getY(), cake.getWidth(), cake.getHeight());
		for (Cake c : cakes) {
			if (r.intersects(new Rectangle(c.getX(), c.getY(), c.getWidth(), c.getHeight())) && c != cake) {
				if (c.getX() > cake.getX()) {
					c.setDirection(Direction.LEFT);
				} else {
					c.setDirection(Direction.RIGHT);
				}
				return c;
			}
		}
		return null;
	}

	public int getDamage() {
		return damage;
	}

	public void setDamage(int damage) {
		this.damage = damage;
	}
}
